package com.frame.util;

import java.io.Serializable;
import java.sql.*;
import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.TableGenerator;
import org.hibernate.type.Type;

import com.frame.database.TableBean;
import com.frame.database.util.Seq;
import com.frame.util.BeanUtils;

/**
 * hibernate主键Id生成器（支持整形和字符型）
 *
 * @author 王海锋
 *
 */
public class IDGenerator  extends TableGenerator{

    public static final String KEYGEN="key_generator";
    public static final String KEYLENGTH = "keylength";
    public static final String KEYTYPE="keytype";
    private String length;
    private String keytype;
    private String sql;
    private Serializable next;
    private String column;

    public void configure(Type type, Properties params, Dialect d) {
//        super.configure(type, params, d);
        column = params.getProperty("column");
        if (column==null) column = params.getProperty(PersistentIdentifierGenerator.PK);
        sql = "select STARTNUM from "+KEYGEN+" where keyname ='"+column+"'";
        length=params.getProperty(KEYLENGTH);
        keytype=params.getProperty(KEYTYPE);
        if(length==null || "".equals(length))
            length="0";
        if(keytype==null || "".equals(keytype))
            keytype="Integer";
    }

    public synchronized Serializable generate(SessionImplementor session, Object obj)  throws HibernateException {
//      int val = ( (Integer) super.generate(session, obj) ).intValue();
//      return val;
        try{
            TableBean bean=(TableBean)obj;
            //如果手动赋了主键值，则不用再自动增长
            if(bean.getTableKey()!=null){
                Object keyobj=BeanUtils.getValue(bean, bean.getTableKey().getKeyCode());
                if(keyobj!=null && !"".equals(keyobj))
                    return (Serializable)keyobj;
            }
            if (sql!=null)
                getNext( session.connection() );
        }catch(Exception e){
            throw new HibernateException("数据表映射文件类没有实现TableBean接口",e);
        }
        return next;
    }
    private void getNext(Connection conn) throws HibernateException{
        next=new Seq(conn).getKeyId(column.toUpperCase(),keytype,Integer.parseInt(length));
    }
}
